import { Schema, h, makeArray } from "koishi"
import { executeQuery } from "minato"

export const name = "-lnnbot-guild-member-requests"

export const Config = Schema.object({
  branches: Schema.array(Schema.object({
    condition: Schema.any(), // import("minato").Query.Expr<{ platform: string; guildId: string; userId: string; message: string; question?: string; answer?: string; authority: number; permissions: string[]; qqLevel: number }>
    result: Boolean,
  })),
})

export function apply(ctx, config) {
  const requestNotices = Object.create(null)

  ctx.on("guild-member-request", async session => {
    const { assignee, locales } = await session.observeChannel(["assignee", "locales"])
    if (session.selfId !== assignee) return ctx.logger.debug("skipped non-assignee", { assignee, session })
    const i18n = (...args) => ctx.i18n.render(locales, ...args)

    let userId = session.userId
    const user = await session.bot.getUser(userId).catch(() => session.event.user) ?? {}
    let c = []
    let avatar = h("")
    if (user.avatar) {
      const u = new URL(user.avatar)
      u.searchParams.set("spec", "100")
      avatar = h.image(u.href)
    }
    c.push(...i18n(["lnnbot.guild-member-requests.request"], { ...user, avatar }))
    const message = h.unescape(session.content)
    let question, answer
    if (message) {
      const m = message.match(/^问题：(.+)\n答案：(.+)$/)
      if (m) {
        question = m[1]
        answer = m[2]
        c.push(h("br"), ...i18n(["lnnbot.guild-member-requests.question-answer"], m.slice(1)))
      } else {
        c.push(...i18n(["general.comma"]), ...i18n(["lnnbot.guild-member-requests.comment"], [message]))
      }
    }
    const data = {
      platform: session.platform,
      guildId: session.guildId,
      userId: session.userId,
      message,
      question,
      answer,
      ...await session.observeUser(["authority", "permissions"]),
      qqLevel: (await session.onebot?.getStrangerInfo(session.userId).catch(() => null))?.qqLevel,
    }
    ctx.logger.debug("data", data)
    let result
    for (let { condition, result } of config.branches) {
      const matches = executeQuery(data, condition)
      ctx.logger.debug("branch", { condition, matches, result })
      if (matches) {
        result = makeArray(result)
        if (result[0] === false) result[1] ??= session.text("lnnbot.guild-member-requests.reject-message")
        session.bot.handleGuildMemberRequest(session.messageId, ...result)
        if (session.elements.length) c.push(h("br"))
        else c.push(...i18n(["general.comma"]))
        c.push(...i18n([`lnnbot.guild-member-requests.${result[0] ? "approved" : "rejected"}`]))
        break
      }
    }
    const mid = [session.platform, session.channelId, session.userId].join(":")
    if (requestNotices[mid]) {
      (await requestNotices[mid]).forEach(m => session.bot.deleteMessage(session.channelId, session.messageId))
      requestNotices[mid].dispose?.()
      delete requestNotices[mid]
    }
    requestNotices[mid] = session.send(c)
    requestNotices[mid].dispose = ctx.setTimeout(() => delete requestNotices[mid], 120_000)
  })

  ctx.i18n.define("zh-CN","lnnbot.guild-member-requests",{
    request: "{avatar}{name} ({id}) 申请加入本群",
    comment: "验证消息：{0}",
    "question-answer": "问题：{0}<br/>答案：{1}",
    approved: "已同意。",
    rejected: "已拒绝。",
    "reject-message": "您的申请被判定为不正常，LNNBot 已自动拒绝，请重试",
  })
}
